<script setup lang="ts">
import { getMyMenus, getMyRoleNmaes, getMyMenuHandle, getMyInfo } from '@/api/user'
import { roleSign } from '@/api/sign'
import Nav from '@/components/Nav.vue'
import { useUserStore } from '@/stores'
import {
  formatMenu,
  formatRoutes,
  saveMenuMap,
  saveMenuHandleIds,
  saveMenuHandleMap,
  clearUserMenus
} from '@/util/menu'
import type { WindowTag } from '@/types/menu'
import { getUserMenus, setUserMenus, clearAllInfo, setJwt, getJwt } from '@/util/token'
import { onMounted, ref, defineAsyncComponent } from 'vue'
import { useRouter } from 'vue-router'
import { icon, Bell } from '@/util/icons'
import AsyncComponent from '@/components/AsyncComponent.vue'
import { ElMessage, ElNotification } from 'element-plus'
import { connect, onInform } from '@/api/msg'
import 'element-plus/theme-chalk/el-notification.css'
import type { MsgTable } from '@/types/msg'
import { UrlFormat } from '@/util/request'
const userStore = useUserStore()
const showSelect = ref(false)
const showUI = ref(false)
const router = useRouter()

// 主页组件dom
const navRef = ref<{
  clearWindow: () => void
  pushTag: (tag: WindowTag) => void
  closeTag: () => void
}>()
// 定义异步组件路径 角色 首页的加载
let IndexPath = ref('')
// 获取用户信息
async function userInfo() {
  let d = await getMyInfo()
  userStore.info = d.data.user
  userStore.roleNames = d.data.roles
  let rid = userStore.useRoleId
  let role = userStore.roleNames.find((d) => {
    return d.rId == rid
  })
  IndexPath.value = role?.indexPath!
  connect()
}

onMounted(async () => {
  // 判断用户是否选择了一个角色 如果没有选择就获取用户拥有的角色信息并提示用户登陆
  if (!getJwt()) {
    ElMessage.warning('请登录后再重试')
    router.replace({
      name: 'home'
    })
    return
  }
  if (userStore.useRoleId === null) {
    const roleNames = await getMyRoleNmaes()
    userStore.roleNames = roleNames.data
    showSelect.value = true
  } else {
    // 如果有选择角色 那就直接获取菜单数据然后渲染
    let menus = getUserMenus()
    userStore.menus = formatMenu(menus)
    showUI.value = true
    userInfo()
  }
})

// 退出登陆
function logout() {
  clearAllInfo()
  clearUserMenus()
  userStore.info = {}
  userStore.useRoleId = null
  userStore.roleNames = []
  userStore.menus = []
  router.replace({
    name: 'login'
  })
}
// 选择角色登陆
async function login() {
  // 根据选择的用户角色来
  try {
    const token = await roleSign(userStore.useRoleId!)
    if (token.code != 200) {
      return
    }
    setJwt(token.data)
    // 获取用户菜单
    const menus = await getMyMenus()
    const routeData = formatRoutes(menus.data)
    routeData.forEach((r) => {
      router.addRoute('home', r)
    })
    // 保存菜单原始数据
    setUserMenus(menus.data)
    userStore.menus = formatMenu(menus.data)
    // 缓存菜单数据
    saveMenuMap(menus.data)
    // 获取 用户菜单按钮 并保存
    getMyMenuHandle(userStore.useRoleId!).then((d) => {
      saveMenuHandleMap(d.data.smh)
      saveMenuHandleIds(d.data.tags)
      userInfo().then(() => {
        navRef.value?.clearWindow()
      })
    })

    // 关闭登陆提示框
    showSelect.value = false
    // 显示 用户界面
    showUI.value = true
  } catch {
    ElMessage.warning('登录失败')
  }
}

// 个人主页跳转
function routerToUserIindex() {
  router.push({
    name: 'user_index'
  })
}

// 弹框控制
const showDialog = ref(false)

// 系统通知控制
const Inform = defineAsyncComponent(() => import('./Inform.vue'))
const msgNum = ref(0)
onInform(() => {
  msgNum.value++
  ElNotification({
    title: '新公告',
    duration: 1500,
    type: 'warning'
  })
})
</script>
<template>
  <Nav v-if="showUI" ref="navRef">
    <template #default>
      <AsyncComponent :path="IndexPath"></AsyncComponent>
    </template>
    <template #head>
      <div class="user">
        <el-icon class="icon-button icon-margin"><icon.Setting /></el-icon>
        <el-badge class="msg-box" :hidden="msgNum <= 0" :max="99" type="warning" :value="msgNum">
          <el-icon class="msg icon-button" @click="showDialog = true">
            <Bell />
          </el-icon>
        </el-badge>
        <el-popover placement="top-start" trigger="hover">
          <template #reference>
            <el-avatar
              class="user-head"
              @click="routerToUserIindex"
              :icon="(icon as any)[userStore.info?.head!]"
              :src="UrlFormat(userStore.info?.head!)"
            />
          </template>
          <template #default>
            <el-row class="user-con-buttons">
              <el-col :span="24">
                <el-button text @click="showSelect = true">切换角色</el-button>
              </el-col>
              <el-col :span="24">
                <el-button text @click="routerToUserIindex">个人中心</el-button>
              </el-col>
            </el-row>
          </template>
        </el-popover>
        <el-link class="logout" @click="logout">退出登陆</el-link>
      </div>
    </template>
  </Nav>
  <el-dialog
    v-model="showSelect"
    :close-on-click-modal="userStore.useRoleId! > 0"
    :close-on-press-escape="userStore.useRoleId! > 0"
    :show-close="userStore.useRoleId! > 0"
    :width="'300px'"
  >
    <template #header>
      <h2>请选择角色登陆</h2>
    </template>
    <el-row :justify="'center'">
      <el-select v-model="userStore.useRoleId" clearable placeholder="选择角色">
        <el-option
          v-for="item in userStore.roleNames"
          :key="item.rId"
          :label="item.name"
          :value="item.rId"
          :disabled="item.status != '1'"
        />
      </el-select>
      <div class="buttons">
        <el-button type="success" :disabled="!(userStore.useRoleId! > 0)" @click="login"
          >确认登陆</el-button
        >
        <el-button type="warning" @click="logout">退出登陆</el-button>
      </div>
    </el-row>
  </el-dialog>
  <el-dialog destroy-on-close @close="msgNum = 0" v-model="showDialog" title="系统公告" top="5vh">
    <Inform />
  </el-dialog>
</template>
<style lang="less" scoped>
.role-login-box {
  width: 100%;
  height: 100%;
  position: absolute;
  background: gray;
  top: 0;
}

.buttons {
  margin-top: 20px;
}

.user {
  height: 100%;
  display: flex;
  align-items: center;

  .msg-box {
    margin-right: 30px;
    font-size: 10px;
  }
  .icon-button {
    cursor: pointer;
    font-size: 20px;
  }
  .icon-margin {
    margin-right: 10px;
  }
  .el-avatar {
    &:hover {
      cursor: pointer;
    }
  }

  .user-head {
    height: 35px;
    width: 35px;
  }

  .logout {
    margin-left: 10px;
  }
}

:deep(.el-option *) {
  user-select: none;
}

.user-con-buttons {
  .el-button {
    margin: 5px 0px;
    width: 100%;
  }
}
</style>
<style>
.highlight-info {
  color: var(--el-color-primary);
  cursor: pointer;
  text-decoration: 1px var(--el-color-primary) solid;
}

.highlight-success {
  color: var(--el-color-success);
  cursor: pointer;
}

.highlight-danger {
  color: var(--el-color-danger);
  cursor: pointer;
}
</style>
